﻿#include <iostream>
#include <vector>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <queue>
#include <algorithm>
#include <numeric>
#include <stack>

using namespace std;


//(典中典)面试题 16.09 运算
//请实现整数数字的乘法、减法和除法运算，运算结果均为整数数字，
//程序中只允许使用加法运算符和逻辑运算符，允许程序中出现正负常数，不允许使用位运算。
//你的实现应该支持如下操作：
//Operations() 构造函数
//minus(a, b) 减法，返回a - b
//multiply(a, b) 乘法，返回a * b
//divide(a, b) 除法，返回a / b
//示例：
//Operations operations = new Operations();
//operations.minus(1, 2); //返回-1
//operations.multiply(3, 4); //返回12
//operations.divide(5, -2); //返回-2

class Operations {
    using ll = long long;
    ll pos[31] = { 0 };
    ll neg[31] = { 0 };
public:
    Operations() {
        ll p = 1, np = -1;
        pos[0] = 1;
        neg[0] = -1;
        for (int i = 1; i < 31; ++i) {
            p = (p + p);
            np = (np + np);
            pos[i] = p;
            neg[i] = np;
        }
    }

    ll opposite(int a) {
        //这个函数没有解决当 a 是INT_MIN的情况，所以其他函数在调用的时候要注意
        if (a == 0) { return 0; }
        if (a > 0) {
            ll ret = 0;
            for (int i = 30; i >= 0; i = i + (-1)) {
                if (neg[i] + a >= 0) {
                    ret = ret + neg[i];
                    a = a + neg[i];
                }
            }
            return ret;
        }
        else {
            ll ret = 0;
            for (int i = 30; i >= 0; i = i + (-1)) {
                if (pos[i] + a <= 0) {
                    ret = ret + pos[i];
                    a = a + pos[i];
                }
            }
            return ret;
        }
    }

    ll abs(int a) {
        return a < 0 ? opposite(a) : a;
    }

    int minus(int a, int b) {
        return a + (int)opposite(b);
    }

    int multiply(int a, int b) {
        if (a == 0 || b == 0) {
            return 0;
        }
        if (a == 1) {
            return b;
        }
        if (b < 0) {
            return opposite(multiply(a, opposite(b)));
        }
        // a + a = 2 * a
        // 2 * a + 2 * a = 4 * a
        // 4 * a + 4 * a = 8 * a
        // pos:2^0, 2^1, 2^2, ..., 2^30
        ll count = 0;
        int res = 0;
        for (int i = 30; i >= 0; i = i + (-1)) {
            if (count + pos[i] <= b) {
                int copy = i;
                int copys = a;
                while (copy--) {
                    // 假设循环中的逻辑执行了 c 次
                    // a 变成 a * (2 ^ c)
                    copys = copys + copys;
                }
                res = res + copys;
                count = count + pos[i];
                if (count == b) {
                    break;
                }
            }
        }
        return res;
    }

    int divide(int a, int b) {
        if (a == 0) {
            return 0;
        }
        if (b == 1) {
            return a;
        }
        if (b == -1) {
            return opposite(a);
        }
        if (a > 0) {
            if (b == INT_MIN) {
                return 0;
            }

            if (b < 0) {
                return opposite(divide(a, opposite(b)));
            }
            if (b > a) {
                return 0;
            }
            if (a == b) {
                return 1;
            }
            int times = 1;
            int prev = b;
            int prev2 = times;
            long long copy = b;
            while (copy < a) {
                prev = copy;
                copy = copy + copy;
                prev2 = times;
                times = times + times;
            }
            return prev2 + divide(minus(a, prev), b);
        }
        else {
            if (b == INT_MIN) {
                return 0;
            }
            if (b > 0) {
                return opposite(divide(a, opposite(b)));
            }
            if (b < a) {
                return 0;
            }
            return divide(abs(a), abs(b));
        }
    }
};

//int main() {
//    Operations* ss = new Operations();
//    //cout << INT_MIN << endl;
//    //int ret = ss->opposite(INT_MIN);
//    //int ret = ss->opposite(100);
//    //cout << ret << endl;
//    ////int r1 = ss->minus(0, ret);
//    //int r1 = ss->multiply(21474836, ret);
//    ////cout << (0 - INT_MAX) << endl;
//    //cout << (-100 * (21474836)) << endl;
//    //cout << r1;
//
//    //cout << ret << endl;
//    //int r1 = ss->minus(0, ret);
//    int r1 = ss->divide(-2147483648, 1);
//    //cout << (0 - INT_MAX) << endl;
//    cout << (-2147483648 / 1) << endl;
//    cout << r1;
//
//    return 0;
//}


// 
// _蓝十三C++研爬树的甲壳虫
// 题目描述
//有一只甲壳虫想要爬上一颗高度为 n 的树，它一开始位于树根，高度为 0，
//当它尝试从高度 i − 1 爬到高度为 i 的位置时有 Pi 的概率会掉回树根，求它从树根爬到树顶时，经过的时间的期望值是多少。
// 输入格式
//输入第一行包含一个整数 n 表示树的高度。
//接下来 n 行每行包含两个整数 xi, yi，用一个空格分隔，表示pi = xi / yi
// 输出格式
//输出一行包含一个整数表示答案，答案是一个有理数，请输出答案对质数 998244353 取模的结果。
//其中有理数蓝桥杯2022年第十三届省赛真题爬树的甲壳虫2对质数 P 取模的结果是整数 c 满足 0 ≤ c < P 且 c · b ≡ a(mod P)
// 样例输入
//1
//1 2
//样例输出
//2
//提示
//对于 20 % 的评测用例，n ≤ 2，1 ≤ xi < yi ≤ 20 ；
//对于 50 % 的评测用例，n ≤ 500，1 ≤ xi < yi ≤ 200 ；
//对于所有评测用例，1 ≤ n ≤ 100000，1 ≤ xi < yi ≤ 109 。
//
// 要完成这道题，应该使用快速幂，
// 先做50. Pow(x, n)  https://leetcode.cn/problems/powx-n/submissions/604815057/ 
// 和372. 超级次方 https://leetcode.cn/problems/super-pow/description/ 

using ll = long long;

#define MOD 998244353 

// a^n
ll qpow(ll a, ll n, int mod) {
    if (n < 0) {
        a = 1.0 / a;
        n = -n;
    }

    ll ret = 1;
    while (n) {
        if (1 & n) {
            ret = ret * a % MOD;
        }
        a = (a * a) % MOD;
        n >>= 1;
    }
    return ret;
}

int main()
{
    int n;
    cin >> n;
    vector<ll> X(n);
    vector<ll> Y(n);
    for (int i = 0; i < n; ++i) {
        cin >> X[i] >> Y[i];
    }

    ll ret = 0;
    for (int i = 0; i < n; ++i) {
        ret = ((ret + 1) * Y[i]) % MOD * qpow(Y[i] - X[i], MOD - 2, MOD) % MOD;
    }
    cout << ret;

    return 0;
}







// _LCR 163 找到第 k 位数字